package com.whosly.study.webflux.service;

import com.example.grpc.openapi.response.ResponseResult;
import com.google.protobuf.Any;
import com.google.protobuf.BoolValue;
import com.openapi.proto.CreateOpenAPIGrpc;
import com.openapi.proto.CreateOpenAPIProto;
import io.grpc.stub.StreamObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

public class CreateGrpcServer extends CreateOpenAPIGrpc.CreateOpenAPIImplBase {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    public CreateGrpcServer() {
        //.
    }

    @Override
    public void create(CreateOpenAPIProto.CreateRequest request, StreamObserver<CreateOpenAPIProto.RpcResponseResult> responseObserver) {
        CreateOpenAPIProto.RpcResponseResult rpcResponseResult;

        try{
            String name = request.getName();

            logger.info("nme:{}.", name);

            rpcResponseResult = buildSuccessRpcResponseResult(getBooleanAny(true));
        }catch (Exception e){
            rpcResponseResult = handleException(e);
        }

        responseObserver.onNext(rpcResponseResult);
        responseObserver.onCompleted();
    }


    private Any getBooleanAny(Boolean result) {
        if (result == null) {
            return null;
        }

        // 使用Any.pack(Message msg);方法进行序列化，其中msg对象就是proto文件中定义的业务Response模型
        return Any.pack(BoolValue.newBuilder().setValue(result).build());
    }


    private CreateOpenAPIProto.RpcResponseResult buildSuccessRpcResponseResult(Any data) {
        // 将返回得到的Any对象，使用setData(Any any);方法添加到RpcResponseResult对象中
        if (data == null) {
            return CreateOpenAPIProto.RpcResponseResult.newBuilder()
                    .setCode("A02").build();
        }
        return CreateOpenAPIProto.RpcResponseResult.newBuilder()
                .setCode(ResponseResult.SUCCESS_CODE).setData(data).build();
    }


    private CreateOpenAPIProto.RpcResponseResult handleException(Exception e) {
        CreateOpenAPIProto.RpcResponseResult rpcResponse;

        e.printStackTrace();
        rpcResponse = buildFailRpcResponseResult("B00001", "系统执行出错", e.getMessage());

        return rpcResponse;
    }

    private CreateOpenAPIProto.RpcResponseResult buildFailRpcResponseResult(String code, String message,
                                                                                     String subMsg) {
        CreateOpenAPIProto.RpcResponseResult.Builder builder =
                CreateOpenAPIProto.RpcResponseResult.newBuilder();
        if (StringUtils.hasText(subMsg)) {
            builder.setSubMsg(subMsg);
        }
        return builder.setCode(code == null ? "F01" : code).setMsg(message).build();
    }

}
